<!--
 * @author hugh
 * @time  2021-01-10 11:40
 * @title  角色管理
 * @desc
 -->
<template>
  <div class="pages">
    <el-form :inline="true" :model="data.seekForm" class="header-from">
      <el-form-item label="角色名称">
        <el-input size="mini" v-model="data.seekForm.name" placeholder="请输入角色名称"></el-input>
      </el-form-item>
      <el-form-item label="角色标识">
        <el-input size="mini" v-model="data.seekForm.code" placeholder="请输入角色标识"></el-input>
      </el-form-item>
      <el-form-item label="是否超级管理员">
        <el-select size="mini" v-model="data.seekForm.administrator" placeholder="请选择">
          <el-option v-for="(item, index) in data.options" :key="index" :label="item.label" :value="item.value"
            @change="onSelectRole">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button icon="el-icon-search" size="mini" type="success" @click="getDataList">查询</el-button>
        <el-button icon="el-icon-edit" size="mini" type="warning" @click="whiteRow('AddRoleInfoModal', -1, data.tableData)">
          添加
        </el-button>
      </el-form-item>
    </el-form>

    <el-card :body-style="{padding: '0px'}">
      <el-table :border="true" size="mini" :data="data.tableData" :height="data.tableHeight" class="table-box">
        <el-table-column label="序号" width="100">
          <template #default="scope">
            {{ scope.$index + 1 }}
          </template>
        </el-table-column>
        <el-table-column prop="roleId" label="角色ID" width="100">
        </el-table-column>
        <el-table-column prop="name" label="角色名称" width="160">
        </el-table-column>
        <el-table-column prop="code" label="角色标识">
        </el-table-column>
        <el-table-column prop="administrator" label="超级管理员" width="100">
          <template #default="scope">
            {{ scope.row.administrator ? '是' : '否' }}
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="创建时间" width="180">
        </el-table-column>
        <el-table-column prop="status" label="操作" fixed="right" min-width="360">
          <template #default="scope">
            <el-button @click.prevent="deleteRow(scope.$index, scope.row.roleId, data.tableData)" type="danger"
              size="mini">删除</el-button>
            <el-button @click.prevent="whiteRow('UpdataRoleInfoModal', scope.$index, scope.row)" type="warning"
              size="mini">编辑</el-button>
            <el-button @click.prevent="whiteRow('MenuModal', scope.$index, scope.row)" type="primary"
              size="mini">
              角色菜单</el-button>
            <el-button @click.prevent="whiteRow('PermissionsModal', scope.$index, scope.row)" type="success"
              size="mini">角色权限</el-button>
          </template>
        </el-table-column>
      </el-table>
      <div class="padding-sm">
        <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="data.currentPage"
          :page-count="data.total" :page-size="data.size" layout="prev, pager, next">
        </el-pagination>
      </div>
    </el-card>
    <el-dialog :title="data.dialogModal === 'AddRoleInfoModal' ? '添加角色' : '编辑角色'"
      :model-value="data.dialogModal === 'UpdataRoleInfoModal' || data.dialogModal === 'AddRoleInfoModal'"
      @close="resetForm('ruleFormRef')">
      <el-form :model="data.formData" :rules="data.rules" ref="ruleFormRef">
        <el-form-item label="角色名称" prop="name" :label-width="data.formLabelWidth">
          <el-input v-model="data.formData.name" autocomplete="off" placeholder="请输入角色名称"></el-input>
        </el-form-item>
        <el-form-item label="角色标识" prop="code" :label-width="data.formLabelWidth">
          <el-input v-model="data.formData.code" autocomplete="off" placeholder="请输入角色标识"></el-input>
        </el-form-item>
        <el-form-item label="选择身份" :label-width="data.formLabelWidth">
          <el-checkbox v-model="data.formData.administrator">是否超级管理员</el-checkbox>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="resetForm('ruleFormRef')">取 消</el-button>
          <el-button type="primary" @click="submitForm('ruleFormRef')">确 定</el-button>
        </span>
      </template>
    </el-dialog>
    <el-dialog title="菜单管理" :model-value="data.dialogModal === 'MenuModal'" @close="resetChecked('menuTree')">
      <el-form>
        <el-form-item class="margin-left-lagre">
          <el-checkbox v-model="allMenu" :label="true" @change="onCheckbox('menuTree')">全部</el-checkbox>
          <el-tree :data="data.menus" ref="menuTree" show-checkbox node-key="menuId" default-expand-all
            :default-checked-keys="data.checkMenus" :props="data.defaultProps" @check="onChangeTree">
          </el-tree>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="resetChecked('menuTree')">取 消</el-button>
          <el-button type="primary" @click="changeChecked('menuTree')">确 定</el-button>
        </span>
      </template>
    </el-dialog>
    <el-dialog title="权限管理" :model-value="data.dialogModal === 'PermissionsModal'" @close="resetChecked('permissionsTree')">
      <el-form ref="ruleFromRef">
        <!-- <el-form-item label="选择服务" :label-width="formLabelWidth">
          <el-cascader v-model="selectServe" :options="services" placeholder="请选择所属服务" :props="{ checkStrictly: true }"
            clearable @change="onSeviceChange"></el-cascader>
        </el-form-item> -->
        <el-form-item label="选择服务" :label-width="data.formLabelWidth">
          <el-row>
            <el-col :span="12">
              <div>
                <el-tree :data="data.services" ref="serviceTree" node-key="serviceId" :expand-on-click-node="false"
                  default-expand-all :default-expanded-keys="data.selectServe" :default-checked-keys="data.selectServe"
                  :props="data.defaultProps" @check="onChangeServeTree" @node-click="onOpenServeTree">
                </el-tree>
              </div>
            </el-col>
            <el-col :span="12">
              <div>
                <div class="flex justify-between">
                  <span>服务权限-{{ data.nowService }}：</span>
                  <el-checkbox v-model="allPermission" :label="true" @change="onCheckbox('permissionsTree')">全部
                  </el-checkbox>
                </div>
                <el-tree :data="data.permissions" ref="permissionsTree" default-expand-all show-checkbox
                  node-key="permissionId" :default-expanded-keys="data.allPermissionIds"
                  :default-checked-keys="data.checkPermissions" :props="data.defaultProps" @check="onChangeTree">
                </el-tree>
              </div>
            </el-col>
          </el-row>

        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="resetChecked('permissionsTree')">取 消</el-button>
          <el-button type="primary" @click="changeChecked('permissionsTree')">确 定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>
<script setup lang="ts">
import {
  reactive,
  getCurrentInstance,
  ref,
  watch
} from 'vue'
import {
  useRouter
} from 'vue-router'
import {
  fromLength
} from '@/common/from_role'
import {
  useStore
} from 'vuex'
// 路由
const router = useRouter()
// vuex
const store = useStore()
// 绑定挂载全局对象
const {
  proxy
} = getCurrentInstance() as any
const {
  list,
  create,
  update,
  del,
  roleMenu,
  roleMenuTree,
  rolePermissionTree,
  updatePermission
} = proxy.$api.Role
const baseMenu: any = {
  css: '',
  hidden: true,
  menu: 0,
  name: '',
  parentId: 0,
  path: '',
  sort: 0,
  url: '',
  createTime: '',
  checked: false,
  clientId: store.state.clientId,
  childs: []
}
const basePermissions = {
  checked: true,
  childs: [],
  isPermission: 0,
  name: '',
  parentId: 0,
  permission: '',
  permissionId: 0,
  remark: '',
  serviceId: 0,
  sort: 0
}
const baseFrom: any = {
  administrator: false,
  clientId: store.state.clientId,
  code: '',
  name: '',
  roleId: 0
}

// 定义参数集合
const data = reactive({
  tableHeight: store.state.tableHeight,
  tableData: [baseFrom],
  seekForm: {
    name: '',
    code: '',
    administrator: 'null',
    clientId: store.state.clientId
  },
  formData: baseFrom,
  formLabelWidth: '120px',
  currentPage: 1,
  size: 20,
  total: 100,
  menus: [baseMenu],
  checkMenus: [0],
  dialogModal: '',
  defaultProps: {
    children: 'childs',
    label: 'name'
  },
  permissions: [basePermissions],
  checkPermissions: [0],
  menuIds: [],
  rules: {
    name: fromLength('请输入角色名称'),
    code: fromLength('请输入角色标识')
  },
  options: [{
    value: 'null',
    label: '全部'
  }, {
    value: '0',
    label: '否'
  }, {
    value: '1',
    label: '是'
  }],
  services: [{
    id: 0,
    name: '标题',
    children: []
  }],
  serviceId: 0,
  allIds: [0],
  allPermissionIds: [0],
  selectServe: [],
  nowService: ''
})
// 全选菜单
const allMenu = ref(false)
// 监听全选变化
watch(allMenu, (value: any) => {
  if (value) {
    data.checkMenus = data.allIds
  } else {
    data.checkMenus = []
  }
})
let checkAllPermissions: number[] = []
// 全选权限
const allPermission = ref(false)
const changeChecked = (str: string) => {
  console.log(str)
}
const resetChecked = (str: string) => {
  console.log(str)
}
const onCheckbox = (str: string) => {
  console.log(str)
}
const submitForm = (str: string) => {
  console.log(str)
}
const resetForm = (str: string) => {
  console.log(str)
}
/**
 * 关闭对话框
 */
const hideDialog = () => {
  if (data.dialogModal === 'MenuModal') {
    data.checkMenus = []
  } else if (data.dialogModal === 'PermissionsModal') {
    data.checkPermissions = []
  } else {
    data.formData = {
      administrator: false,
      clientId: store.state.clientId,
      code: '',
      name: '',
      roleId: 0
    }
    data.formData.administrator = false
  }
  data.dialogModal = ''
}
/**
 * 获取角色列表
 */
const getDataList = () => {
  let administrator = null
  if (data.seekForm.administrator !== 'null') {
    administrator = parseInt(data.seekForm.administrator)
  }
  list({
    clientId: data.seekForm.clientId,
    page: data.currentPage,
    size: data.size,
    name: data.seekForm.name,
    code: data.seekForm.code,
    administrator: administrator
  }).then((res: any) => {
    data.tableData = res.records
    data.total = res.pages
  }).catch((err: any) => {
    console.log(err)
  })
}
/**
 * 更新角色权限
 */
const onRolePermission = (status: boolean) => {
  updatePermission({
    all: allPermission,
    roleId: data.formData.roleId,
    permissionIds: checkAllPermissions
  }).then(() => {
    if (status) {
      proxy.$msg('修改角色菜单成功', 1)
      getDataList()
      hideDialog()
    }
  }).catch(() => {
    if (status) {
      proxy.$msg('修改角色菜单失败', 0)
    }
  })
}
const setPackPermissions = (ids: any, status: boolean, isUpdata: boolean) => {
  if (ids.length === 0) {
    return
  }
  for (let j = 0, len = ids.length; j < len; j++) {
    const index = checkAllPermissions.indexOf(ids[j])
    if (index === -1) {
      checkAllPermissions.push(ids[j])
    } else {
      if (!status) {
        checkAllPermissions.splice(index, 1)
      }
    }
  }
  if (isUpdata) {
    onRolePermission(false)
  }
}

// 监听全选变化
watch(allPermission, (value: any) => {
  if (value) {
    data.checkPermissions = data.allPermissionIds
    setPackPermissions(data.allPermissionIds, true, true)
  } else {
    setPackPermissions(data.checkPermissions, false, true)
    data.checkPermissions = []
  }
})

/**
 * 路由跳转
 */
function toRouter(path: string) {
  router.push(path)
}

/**
 * 删除行
 */
function deleteRow(index: number, roleId: number, lists: any) {
  proxy.$dialog('是否删除该条数据?').then(() => {
    del({
      roleId: roleId
    }).then((res: any) => {
      console.log(res)
      proxy.$msg('删除成功', 1)
      lists.splice(index, 1)
      // getDataList()
    }).catch((err: any) => {
      console.log(err)
      proxy.$msg('删除失败', 0)
    })
  })
}

/**
 * 添加行
 */
function onAddRow(param: any) {
  param.clientId = data.seekForm.clientId
  create(param).then((res: any) => {
    proxy.$msg('创建成功', 1)
    getDataList()
    hideDialog()
  }).catch((err: any) => {
    console.log(err)
    hideDialog()
    proxy.$msg('创建失败', 0)
  })
}

/**
 * 获取菜单树
 */
function getRoleMenuTree() {
  // 初始化全选值
  allMenu = false
  roleMenuTree({
    roleId: data.formData.roleId
  }).then((res: any) => {
    const {
      checks,
      tableData,
      ids
    } = proxy.$treeList(res, 'menuId')
    data.checkMenus = checks
    data.menus = tableData
    data.allIds = ids
    // 显示菜单选择dialog
    data.dialogModal = 'MenuModal'
  }).catch((err: any) => {
    console.log(err)
  })
}

/**
 * 获取权限树
 */
function getRolePermissionTree() {
  // 初始化全选值
  allPermission = false
  rolePermissionTree({
    roleId: data.formData.roleId,
    serviceId: data.serviceId
  }).then((res: any) => {
    if (res.length > 0) {
      const {
        checks,
        tableData,
        ids
      } = proxy.$treeList(res, 'permissionId')
      data.allPermissionIds = ids
      data.checkPermissions = checks
      data.permissions = tableData
      setPackPermissions(checks, true, false)
    } else {
      data.permissions = []
      // proxy.$msg("该服务没有权限列表")
    }
    // 显示权限选择dialog
    data.dialogModal = 'PermissionsModal'
  }).catch((err: any) => {
    console.log(err)
  })
}

function onChangeServeTree(key: any, vals: any) {
  data.serviceId = key.serviceId
  data.nowService = key.name
  getRolePermissionTree()
}

function onOpenServeTree(key: any, vals: any) {
  data.serviceId = key.serviceId
  data.nowService = key.name
  getRolePermissionTree()
}
/**
 * 修改行
 */
function onUpdataRow(param: any) {
  update(param).then((res: any) => {
    console.log(res)
    getDataList()
    hideDialog()
    proxy.$msg('更新成功', 1)
  }).catch(() => {
    proxy.$msg('更新失败', 0)
  })
}
/**
 * 更新角色菜单
 */
function onRoleMenu() {
  if ((!allPermission) && data.checkMenus.length <= 0) {
    proxy.$msg('至少选择一项角色菜单', 1)
    return
  }
  roleMenu({
    roleId: data.formData.roleId,
    menuIds: data.checkMenus
  }).then((res: any) => {
    console.log(res)
    proxy.$msg('修改角色菜单成功', 1)
    getDataList()
    hideDialog()
  }).catch((err: any) => {
    console.log(err)
    // hideDialog()
    proxy.$msg('修改角色菜单失败', 0)
  })
}

function handleSizeChange(val: number) {
  console.log(`每页 ${val} 条`)
}

function handleCurrentChange(val: number) {
  data.currentPage = val
  getDataList()
}

function onSubmit() {
  getDataList()
}

function onChangeTree(key: any, vals: any) {
  if (data.dialogModal === 'MenuModal') {
    data.checkMenus = vals.checkedKeys
  } else if (data.dialogModal === 'PermissionsModal') {
    if (vals.checkedKeys.length > 0) {
      if (vals.checkedKeys.length > data.checkPermissions.length) { // 增加操作
        setPackPermissions(vals.checkedKeys, true, true)
      } else { // 减少操作
        const subList = proxy.$subArray(data.checkPermissions, vals.checkedKeys)
        setPackPermissions(subList, false, true)
      }
    } else { // 全部取消
      setPackPermissions(data.checkPermissions, false, true)
    }
  }
}

function onChangeDialog() {
  if (data.dialogModal === 'AddRoleInfoModal') {
    onAddRow((data.formData as any))
  } else if (data.dialogModal === 'UpdataRoleInfoModal') {
    onUpdataRow((data.formData as any))
  } else if (data.dialogModal === 'MenuModal') {
    onRoleMenu()
  } else if (data.dialogModal === 'PermissionsModal') {
    onRolePermission(true)
  }
}

function onChangeApp(id: number) {
  data.formData.clientId = id
  data.seekForm.clientId = id
  getDataList()
}

/**
 * 调起编辑dialog
 */
function whiteRow(modal: string, index: number, item: any) {
  if (index > -1) {
    for (const key in item) {
      data.formData[key] = item[key]
    }
  } else {
    hideDialog()
  }
  if (modal === 'MenuModal') {
    getRoleMenuTree()
  } else if (modal === 'PermissionsModal') {
    checkAllPermissions = []
    data.checkPermissions = []
    getRolePermissionTree()
  } else {
    data.dialogModal = modal
  }
}
function onSelectRole(vals: string) {
  console.log(vals)
  // data.seekForm.administrator=vals
}
/**
 * 选择服务
 */
function onSeviceChange(value: any) {
  if (value && value.length > 0) {
    data.serviceId = value[value.length - 1]
    getRolePermissionTree()
  }
}
onChangeApp(store.state.clientId)
</script>
